
#include "Input.h"

Input input;

//
// Constructor
//

Input::Input() 
{
	inputManager = NULL;
	keyboard     = NULL;
	mouse        = NULL;
}

//
// Destructor
//

Input::~Input()
{
	if(keyboard) keyboard->Unacquire();
	SAFE_RELEASE(keyboard);

	if(mouse) mouse->Unacquire();
	SAFE_RELEASE(mouse);

	SAFE_RELEASE(inputManager);
}

//
// Initialize
//

bool Input::Initialize(HWND window)
{
	// DirectInput
	DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                     IID_IDirectInput8, (VOID**)&inputManager, NULL);

	// Keyboard
	inputManager->CreateDevice(GUID_SysKeyboard, &keyboard, NULL);
	keyboard->SetDataFormat(&c_dfDIKeyboard);
	keyboard->SetCooperativeLevel(window, DISCL_FOREGROUND | DISCL_EXCLUSIVE);

	// Mouse
	inputManager->CreateDevice(GUID_SysMouse, &mouse, NULL);
	mouse->SetDataFormat(&c_dfDIMouse2);
	mouse->SetCooperativeLevel(window, DISCL_EXCLUSIVE | DISCL_FOREGROUND);

	// Get the input devices
	AcquireDevices();

	return true;
}

//
// AcquireDevices
//

void Input::AcquireDevices()
{
	if(keyboard)
		keyboard->Acquire();
	if(mouse)
		mouse->Acquire();
}

//
// Keys
//

bool Input::KeyPressed(uchar key) const
{
	return (keyBuffer[key] & 0x80) != 0;
}

bool Input::Prev_KeyPressed(uchar key) const
{
	return (keyBuffer_p[key] & 0x80) != 0;
}

bool Input::KeyHeld(uchar key) const
{
	return (keyBuffer[key] & 0x80) && (keyBuffer_p[key] & 0x80);
}

bool Input::KeyPressedOnce(uchar key) const
{
	return (keyBuffer[key] & 0x80) && !(keyBuffer_p[key] & 0x80);
}

bool Input::KeyReleased(uchar key) const
{
  return !(keyBuffer[key] & 0x80) && (keyBuffer_p[key] & 0x80);
}

//
// UpdateDevices
//

void Input::UpdateDevices()
{
	ScanKeyboard();
	ScanMouse();
}

//
// ScanKeyboard
//

void Input::ScanKeyboard()
{
	if(keyboard)
	{
		// Saves previous state to previous keys
		memcpy(&keyBuffer_p, &keyBuffer, sizeof(keyBuffer));

		// Scans in new key state
		keyboard->GetDeviceState(sizeof(keyBuffer), &keyBuffer);
	}
}

//
// ScanMouse
//

void Input::ScanMouse()
{
	if(mouse)
	{
		// Saves previous state to previous keys
		memcpy(&mouseBuffer_p, &mouseBuffer, sizeof(mouseBuffer));

		// Scans in new key state
		ZeroMemory(&mouseBuffer, sizeof(mouseBuffer));
		if(FAILED(mouse->GetDeviceState(sizeof(DIMOUSESTATE2), &mouseBuffer)))
    {
      // If input is lost then acquire and keep trying 
			HRESULT hr;
			do { hr = mouse->Acquire(); }
      while( hr == DIERR_INPUTLOST );
      return; 
    }

		//mouseCoord.x += mouseBuffer.lX;
		//mouseCoord.y += mouseBuffer.lY;
		//mouseCoord.z += mouseBuffer.lZ;
	}
}

//
// GetText
//

void Input::GetText(string &str, ushort minSize)
{
	// Scan Keys
	if(KeyPressedOnce(DIK_A)) str.push_back('a');
	if(KeyPressedOnce(DIK_B)) str.push_back('b');
	if(KeyPressedOnce(DIK_C)) str.push_back('c');
	if(KeyPressedOnce(DIK_D)) str.push_back('d');
	if(KeyPressedOnce(DIK_E)) str.push_back('e');
	if(KeyPressedOnce(DIK_F)) str.push_back('f');
	if(KeyPressedOnce(DIK_G)) str.push_back('g');
	if(KeyPressedOnce(DIK_H)) str.push_back('h');
	if(KeyPressedOnce(DIK_I)) str.push_back('i');
	if(KeyPressedOnce(DIK_J)) str.push_back('j');
	if(KeyPressedOnce(DIK_K)) str.push_back('k');
	if(KeyPressedOnce(DIK_L)) str.push_back('l');
	if(KeyPressedOnce(DIK_M)) str.push_back('m');
	if(KeyPressedOnce(DIK_N)) str.push_back('n');
	if(KeyPressedOnce(DIK_O)) str.push_back('o');
	if(KeyPressedOnce(DIK_P)) str.push_back('p');
	if(KeyPressedOnce(DIK_Q)) str.push_back('q');
	if(KeyPressedOnce(DIK_R)) str.push_back('r');
	if(KeyPressedOnce(DIK_S)) str.push_back('s');
	if(KeyPressedOnce(DIK_T)) str.push_back('t');
	if(KeyPressedOnce(DIK_U)) str.push_back('u');
	if(KeyPressedOnce(DIK_V)) str.push_back('v');
	if(KeyPressedOnce(DIK_W)) str.push_back('w');
	if(KeyPressedOnce(DIK_X)) str.push_back('x');
	if(KeyPressedOnce(DIK_Y)) str.push_back('y');
	if(KeyPressedOnce(DIK_Z)) str.push_back('z');
	if(KeyPressedOnce(DIK_0)) str.push_back('0');
	if(KeyPressedOnce(DIK_1)) str.push_back('1');
	if(KeyPressedOnce(DIK_2)) str.push_back('2');
	if(KeyPressedOnce(DIK_3)) str.push_back('3');
	if(KeyPressedOnce(DIK_4)) str.push_back('4');
	if(KeyPressedOnce(DIK_5)) str.push_back('5');
	if(KeyPressedOnce(DIK_6)) str.push_back('6');
	if(KeyPressedOnce(DIK_7)) str.push_back('7');
	if(KeyPressedOnce(DIK_8)) str.push_back('8');
	if(KeyPressedOnce(DIK_9)) str.push_back('9');

	if(KeyPressedOnce(DIK_SPACE)) str.push_back(' ');
	if(KeyPressedOnce(DIK_PERIOD)) str.push_back('.');
	if(KeyPressedOnce(DIK_BACKSPACE) && str.size() > minSize)
		str.erase(str.end()-1);
}
